package aditii.impl.DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import util.ConnectionManager;
import util.Instances;
import aditii.domain.Cliente;
import aditii.domain.Funcionario;
import aditii.domain.Pessoa;
import aditii.exceptions.QueryNaoConcluidaException;
import aditii.interfaces.DAO.PessoaDAO;

public class PessoaDAOImpl implements PessoaDAO {

	private Connection conn;

	public PessoaDAOImpl(DataSource datasource) throws SQLException {
		conn = datasource.getConnection();
	}
	public PessoaDAOImpl() {

	}
	
	@Override
	public List listarPessoas(String tabela) throws SQLException {
		conn = ConnectionManager.con();
		String sql = "SELECT * FROM " + tabela;
		PreparedStatement statement = conn.prepareStatement(sql);
		ResultSet resultset = statement.executeQuery();
		if (tabela.equals("cliente")) {
			List<Cliente> clientes = new ArrayList<Cliente>();
			while (resultset.next()) {
				Cliente cliente = Instances.getInstanceCliente();
				cliente.setNome(resultset.getString("nome"));
				cliente.setEmail(resultset.getString("email"));
				cliente.setRua(resultset.getString("rua"));
				cliente.setCidade(resultset.getString("cidade"));
				cliente.setBairro(resultset.getString("bairro"));
				cliente.setEstado(resultset.getString("estado"));
				cliente.setLogin(resultset.getString("login"));
				cliente.setSenha(resultset.getString("senha"));
				cliente.setTipoCliente(resultset.getString("tipo"));
				cliente.setNumeroCartao(resultset.getString("numeroCartao"));
				clientes.add(cliente);
			}
			resultset.close();
			statement.close();
			return clientes;
		} else {
			List<Funcionario> funcionarios = new ArrayList<Funcionario>();
			while (resultset.next()) {
				Funcionario funcionario = Instances.getInstanceFuncionario();
				funcionario.setNome(resultset.getString("nome"));
				funcionario.setEmail(resultset.getString("email"));
				funcionario.setRua(resultset.getString("rua"));
				funcionario.setCidade(resultset.getString("cidade"));
				funcionario.setBairro(resultset.getString("bairro"));
				funcionario.setEstado(resultset.getString("estado"));
				funcionario.setLogin(resultset.getString("login"));
				funcionario.setSenha(resultset.getString("senha"));
				funcionario.setFuncao(resultset.getString("funcao"));
				funcionario.setNivel(resultset.getString("nivel"));
				funcionarios.add(funcionario);
			}
			resultset.close();
			statement.close();
			return funcionarios;
		}

	}

	@Override
	public void cadastraPessoa(Pessoa pessoa) throws SQLException {
		String sql = "INSERT INTO pessoa(nome, email,"
				+ "rua, cidade, bairro, estado, login, senha) "
				+ "VALUES(?, ?, ?, ?, ?, ?, ?, ?)";

		PreparedStatement stmt = conn.prepareStatement(sql,
				Statement.RETURN_GENERATED_KEYS);
		stmt.setString(1, pessoa.getNome());
		stmt.setString(2, pessoa.getEmail());
		stmt.setString(3, pessoa.getRua());
		stmt.setString(4, pessoa.getCidade());
		stmt.setString(5, pessoa.getBairro());
		stmt.setString(6, pessoa.getEstado());
		stmt.setString(7, pessoa.getLogin());
		stmt.setString(8, pessoa.getSenha());

		if (stmt.executeUpdate() > 0) {
			ResultSet rs = stmt.getGeneratedKeys();

			if (rs.next()) {
				pessoa.setId(rs.getInt(1));
			}
			rs.close();
			stmt.close();

			insertTipoPessoa(pessoa);
			System.out.println("Pessoa cadastrada com sucesso");
		}

	}

	@Override
	public void excluiPessoa(Pessoa pessoa) throws SQLException, QueryNaoConcluidaException {
		if (excluirTipoPessoa(pessoa) > 0) {
			String sql = "DELETE FROM pessoa WHERE idPessoa = ?";
			PreparedStatement stmt = conn.prepareStatement(sql);
			stmt.setInt(1, pessoa.getId());
			stmt.close();
			System.out.println("Pessoa excluida com sucesso");
		}else{
			throw new QueryNaoConcluidaException("Erro ao excluir registro");
		}
	}

	@Override
	public void editaPessoa(Pessoa pessoa) throws SQLException {

		String sql = "UPDATE pessoa SET nome = ?, email = ?, rua = ?, cidade = ?, "
				+ "bairro = ?, estado = ?, login = ?, senha = ? WHERE "
				+ "idPessoa = ?";

		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setString(1, pessoa.getNome());
		stmt.setString(2, pessoa.getEmail());
		stmt.setString(3, pessoa.getRua());
		stmt.setString(4, pessoa.getCidade());
		stmt.setString(5, pessoa.getBairro());
		stmt.setString(6, pessoa.getEstado());
		stmt.setString(7, pessoa.getLogin());
		stmt.setString(8, pessoa.getSenha());
		stmt.setInt(9, pessoa.getId());

		if (stmt.executeUpdate() > 0) {
			stmt.close();
			editarTipoPessoa(pessoa);
			System.out.println("Pessoa atualizada com sucesso");
		}

	}

	private void insertTipoPessoa(Pessoa pessoa) throws SQLException {
		if (pessoa instanceof Cliente) {
			String sql = "INSERT INTO cliente VALUES (?, ?, ?)";
			PreparedStatement stmt = conn.prepareStatement(sql);
			stmt.setString(1, ((Cliente) pessoa).getTipoCliente());
			stmt.setString(2, ((Cliente) pessoa).getNumeroCartao());
			stmt.setInt(3, pessoa.getId());
			stmt.execute();
			stmt.close();

		} else if (pessoa instanceof Funcionario) {
			String sql = "INSERT INTO funcionario VALUES (?, ?, ?)";
			PreparedStatement stmt = conn.prepareStatement(sql);
			stmt.setString(1, ((Funcionario) pessoa).getFuncao());
			stmt.setString(2, ((Funcionario) pessoa).getNivel());
			stmt.setInt(3, pessoa.getId());
			stmt.execute();
			stmt.close();
		}
	}

	private int excluirTipoPessoa(Pessoa pessoa) throws SQLException {
		String tabela = "";
		if (pessoa instanceof Cliente) {
			tabela = "cliente";
		} else if (pessoa instanceof Funcionario) {
			tabela = "funcionario";
		}
		String sql = "DELETE FROM " + tabela + " WHERE Pessoa_idPessoa = ?";
		PreparedStatement stmt = conn.prepareStatement(sql);
		stmt.setInt(1, pessoa.getId());
		int rowsAffected = stmt.executeUpdate();
		stmt.close();
		return rowsAffected;
	}

	private void editarTipoPessoa(Pessoa pessoa) throws SQLException {
		if (pessoa instanceof Cliente) {
			String sql = "UPDATE cliente SET tipo=?, numeroCartao=? WHERE "
					+ "Pessoa_idPessoa=?";
			PreparedStatement stmt = conn.prepareStatement(sql);
			stmt.setString(1, ((Cliente) pessoa).getTipoCliente());
			stmt.setString(2, ((Cliente) pessoa).getNumeroCartao());
			stmt.setInt(3, pessoa.getId());
			stmt.execute();
			stmt.close();

		} else if (pessoa instanceof Funcionario) {
			String sql = "UPDATE funcionario SET funcao=?, nivel=? WHERE "
					+ "Pessoa_idPessoa=?";
			PreparedStatement stmt = conn.prepareStatement(sql);
			stmt.setString(1, ((Funcionario) pessoa).getFuncao());
			stmt.setString(2, ((Funcionario) pessoa).getNivel());
			stmt.setInt(3, pessoa.getId());
			stmt.execute();
			stmt.close();
		}
	}

}
